<template>
	<onez-view viewid="stage" class="onez-stage">
		<onez-view viewid="stage.ui" class="ui" v-if="ready"
			:style="{ width: ui_width + 'px', height: ui_height + 'px', transform: 'scale(' + zoom + ',' + zoom + ')' }">
			<onez-view :class="['item item-' + item.pos]" v-for="(item, index) in uiItems" :key="index">
				<template v-if="item.children">
					<onez-node v-for="(node, index2) in item.children" position="relative" :key="index2"
						:info="node.info" :show="node.show" :resid="node.resid" :play="node.play"
						:ref="node.key"></onez-node>
				</template>
			</onez-view>
			<template v-if="dialogs" v-for="(dlg, index2) in dialogs">
				<onez-dialog class="dialog" v-if="dlg" :style="{ zIndex: dlg.zIndex }" ref="dialog"></onez-dialog>
			</template>
			<onez-node class="loading" ref="loading" :style="{ opacity: loadingOpacity, zoom: loadingZoom }"
				v-if="loading" :info="node.loading"></onez-node>
		</onez-view>
		<onez-scene ref="sceneA" :scene="sceneOnA" :style="{ zIndex: sceneStepA, opacity: sceneOpacityA }"
			v-if="sceneOnA">
			<slot :stage="stageInfo"></slot>
		</onez-scene>
		<onez-scene ref="sceneB" :scene="sceneOnB" :style="{ zIndex: sceneStepB, opacity: sceneOpacityB }"
			v-if="sceneOnB">
			<slot :stage="stageInfo"></slot>
		</onez-scene>
		<canvas canvas-id="game_canvas" id="game_canvas" class="game_canvas"
			:style="{ opacity: 0, width: game_canvas_width + 'px', height: game_canvas_height + 'px' }"></canvas>
	</onez-view>
</template>
<script>
	import onezView from '../onez-view/onez-view.vue'
	import onezNode from '../onez-node/onez-node.vue'
	import onezScene from '../onez-scene/onez-scene.vue'
	import onezDialog from '../onez-dialog/onez-dialog.vue'
	export default {
		name: 'onez-stage',
		components: {
			onezView,
			onezNode,
			onezDialog,
			onezScene
		},
		props: {
			apiurl: {
				type: String,
				default: 'local'
			},
			game: {
				type: String,
				default: ''
			}
		},
		data() {
			return {
				ui_width: 640,
				ui_height: 640,
				game_canvas_width: 0,
				game_canvas_height: 0,
				zoom: 1,
				info: {},
				uiItems: [],
				dialogs: [],
				node: {
					loading: {
						pic: 'http://cdn.onez.cn/2021/1004/2021100416442620340001.png',
						center: [244, 225],
						speed: 30,
						col: 3,
						row: 3,
						num: 7
					}
				},
				canvasStyle: '',
				dialogZIndex: 1000,
				sceneSwitch: 'A',
				sceneStepA: 0,
				sceneStepB: 0,
				sceneOnA: null,
				sceneOnB: null,
				stageInfo: null,
				sceneOpacityA: 0,
				sceneOpacityB: 0,
				loadingOpacity: 0,
				loadingZoom: 0,
				loading: false,
				ready: false
			};
		},
		mounted() {
			this.init();
		},
		methods: {
			changeScene(sceneName) {
				if (this.sceneSwitch == 'A') {
					this.sceneStepA = 200;
					this.sceneStepB = 100;
					this.sceneOpacityA = 1;
					this.sceneOpacityB = 0;
					this.sceneOnB = sceneName;
				} else {
					this.sceneStepB = 200;
					this.sceneStepA = 100;
					this.sceneOpacityB = 1;
					this.sceneOpacityA = 0;
					this.sceneOnA = sceneName;
				}
				this.showLoading();
				this.$game.wait(this);
				this.$game.scene = sceneName;
			},
			sceneReady(scene) {
				this.stageInfo = {
					scene: scene.info
				};
				this.ready = true;
				if (this.sceneSwitch == 'A') {
					this.sceneStepB = 200;
					this.sceneStepA = 100;
					this.sceneSwitch = 'B';
					this.$game.tween(this, 0.5, {
						sceneOpacityB: 1,
						ease: 'linear.in'
					});
					this.$game.tween(this, 0.5, {
						sceneOpacityA: 0,
						ease: 'linear.in'
					});
					setTimeout(() => {
						this.sceneOnA = null;
					}, 500);
				} else {
					this.sceneStepA = 200;
					this.sceneStepB = 100;
					this.sceneSwitch = 'A';
					this.$game.tween(this, 0.5, {
						sceneOpacityA: 1,
						ease: 'linear.in'
					});
					this.$game.tween(this, 0.5, {
						sceneOpacityB: 0,
						ease: 'linear.in'
					});
					setTimeout(() => {
						this.sceneOnB = null;
					}, 500);
				}
				this.hideLoading();
				this.$game.setData({
					scene: scene.info.name
				});
				this.updateUI(scene.ui);
			},
			showLoading() {
				this.loadingOpacity = 0;
				this.loadingZoom = 0;
				this.loading = true;
				this.$game.tween(this, 0.2, {
					loadingOpacity: 1,
					loadingZoom: 1,
					ease: 'linear.in'
				});
			},
			hideLoading() {
				this.loadingOpacity = 1;
				this.loading = true;
				this.$game.tween(this, 0.3, {
					loadingOpacity: 0,
					ease: 'linear.in'
				});
				setTimeout(() => {
					this.loading = false;
				});
			},
			async dialog(type, data) {
				data.type = type;
				this.dialogZIndex++;
				for (var i = 0; i < this.dialogs.length; i++) {
					if (!this.dialogs[i]) {
						this.dialogs[i] = {
							zIndex: this.dialogZIndex
						};
						await this.$game.wait(this);
						var r = await this.$refs['dialog'][i].update(data);
						this.dialogs[i] = null;
						return r;
					}
				}
				var i = this.dialogs.length;
				this.dialogs.push({
					zIndex: this.dialogZIndex
				});
				await this.$game.wait(this);
				await this.$game.delay(0.1);
				var r = await this.$refs['dialog'][i].update(data);
				this.dialogs[i] = null;
				return r;
			},
			async resize(e) {
				let systemInfo = await this.$game.getSystemInfoSync();
				let width = systemInfo.windowWidth;
				let height = systemInfo.windowHeight;
				let zoom = Math.max(480 / width, 480 / height);
				zoom = Math.max(1, zoom);
				this.ui_width = width * zoom;
				this.ui_height = height * zoom;
				this.zoom = 1 / zoom;
				this.width = width;
				this.height = height;
				this.$game.width = this.width;
				this.$game.height = this.height;
				if (this.infoBack) {
					this.sceneZoom = Math.max(this.height / this.info.height, this.width / this.info.width);
				}
				this.$emit('resize', e);
			},
			async restart() {
				this.ready = false;
				await this.$game.wait(this);
				await this.init();
			},
			async init() {
				var that = this;
				this.showLoading();
				this.$game.apiurl = this.apiurl || 'local';
				this.$game.onResize(this.resize);
				this.info = await this.$game.hook(this, 'start');
				if (this.info.scene) {
					this.changeScene(this.info.scene);
				}
				this.updateUI();
				this.ready = true;
			},
			async updateUI(sceneUI) {
				var itemsArr = [],
					itemsObj = {};
				if (this.info.ui) {
					this.info.ui.forEach(item => {
						var pos = item.pos || 'br';
						if (!itemsObj[pos]) {
							itemsObj[pos] = [];
						}
						itemsObj[pos].push(item);
					});
				}
				if (sceneUI) {
					sceneUI.forEach(item => {
						var pos = item.pos || 'br';
						if (!itemsObj[pos]) {
							itemsObj[pos] = [];
						}
						itemsObj[pos].push(item);
					});
				}
				for (var key in itemsObj) {
					itemsArr.push({
						pos: key,
						children: itemsObj[key]
					});
				}
				this.uiItems = itemsArr;
			},
			canvas(width, height) {
				return new Promise((resolve, reject) => {
					if (!this.game_canvas) {
						this.game_canvas = uni.createCanvasContext('game_canvas', this);
					}
					this.game_canvas_width = width;
					this.game_canvas_height = height;
					this.$game.wait(this);
					this.game_canvas.clearRect(0, 0, width, height);
					resolve(this.game_canvas);
				});
			},
			canvasUrl() {
				return new Promise((resolve, reject) => {
					uni.canvasToTempFilePath({
							canvasId: 'game_canvas',
							success: res => {
								resolve(res.tempFilePath);
							},
							fail: res => {
								resolve(null);
							}
						},
						this
					);
				});
			}
		}
	};
</script>
<style scoped>
	.loading {
		position: absolute;
		left: 50% !important;
		top: 50% !important;
		z-index: 9999;
		opacity: 0;
	}

	.ui {
		pointer-events: none;
		z-index: 888;
		transform-origin: 0 0;
	}

	.onez-stage,
	.ui {
		position: absolute;
		left: 0;
		top: 0;
		width: 100%;
		height: 100%;
		overflow: hidden;
	}

	.ui .item {
		position: absolute;
	}

	.ui .item-tl {
		left: 0;
		top: 0;
	}

	.ui .item-t {
		left: 50%;
		top: 0;
	}

	.ui .item-tr {
		right: 0;
		top: 0;
	}

	.ui .item-cl {
		left: 0;
		top: 50%;
	}

	.ui .item-cc {
		left: 50%;
		top: 50%;
	}

	.ui .item-cr {
		right: 0;
		top: 50%;
	}

	.ui .item-bl {
		left: 0;
		bottom: 0;
	}

	.ui .item-bc {
		left: 50%;
		bottom: 0;
	}

	.ui .item-br {
		right: 0;
		bottom: 0;
	}

	.dialog.message {
		z-index: 1001;
	}

	.game_canvas {
		position: absolute;
		left: 0;
		top: 0;
		pointer-events: none !important;
	}
</style>